﻿#region using statements

using System;
using System.IO;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using NGen;
using NGen.Managers.Pathfinding;

#endregion

namespace Psych.Misc
{
    /// <summary>
    /// 	Represents the current level in the game
    /// </summary>
    public class GameLevel
    {
        public GameLevel()
        {
            //public GameLevel(string p_mapName)

            // load the level map
            LevelImage = GameEngine.GameContent.Load<Texture2D>("Content\\level\\testmap");

            // load the tile map from a file, used to allow enemies to follow the path
           /* LevelGrid = new int[LevelWidth, LevelHeight];
            var reader = new StreamReader("Content\\LevelMaps\\" + p_mapName + ".dat");
            var line = reader.ReadLine();
            StartPosition = new Point(int.Parse(line.Split(' ')[0]), int.Parse(line.Split(' ')[1]));
            line = reader.ReadLine();
            EndPosition = new Point(int.Parse(line.Split(' ')[0]), int.Parse(line.Split(' ')[1]));
            */
          /*  var j = 0;
            while ((line = reader.ReadLine()) != null)
            {
                //populate the 2d level tile map
                var i = 0;
                //for each line, split into a string array on each space
                foreach (var value in line.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
                {
                    LevelGrid[i++, j] = int.Parse(value);
                }
                ++j;
            }*/
        }

        /// <summary>
        /// 	get height of level in tiles
        /// </summary>
        public static int LevelHeight
        {
            get { return 18; }
        }

        /// <summary>
        /// 	get width of level in tiles
        /// </summary>
        public static int LevelWidth
        {
            get { return 18; }
        }

        /// <summary>
        /// 	get size of tiles in pixels
        /// </summary>
        public static int LevelTilesize
        {
            get { return 32; }
        }

        /// <summary>
        /// 	Get offset from top left corner
        /// </summary>
        public static Vector2 MapOffset
        {
            get { return new Vector2(12, 12); }
        }

        /// <summary>
        /// 	get the level image
        /// </summary>
        public Texture2D LevelImage { get; protected set; }

        /// <summary>
        /// 	get the level tile map
        /// </summary>
        public int[,] LevelGrid { get; protected set; }

        /// <summary>
        /// 	get the level start position
        /// </summary>
        public Point StartPosition { get; protected set; }

        /// <summary>
        /// 	get the level end position
        /// </summary>
        public Point EndPosition { get; protected set; }

        /// <summary>
        /// 	convert level grid coordinates to pixel coordinates
        /// </summary>
        /// <param name = "p_position"></param>
        /// <returns></returns>
        public static Vector2 GetScreenCoords(Point p_position)
        {
            var coord = new Vector2
            {
                X = MapOffset.X + (p_position.X * LevelTilesize),
                Y = MapOffset.Y + (p_position.Y * LevelTilesize)
            };
            return coord;
        }

        /// <summary>
        /// 	convert pixel coordinates to level grid coordinates
        /// </summary>
        /// <param name = "p_position"></param>
        /// <returns></returns>
        public static Point GetWorldCoords(Vector2 p_position)
        {
            var coord = new Point
            {
                X = (int)((p_position.X - MapOffset.X) / LevelTilesize),
                Y = (int)((p_position.Y - MapOffset.Y) / LevelTilesize)
            };
            return coord;
        }

        /// <summary>
        /// 	snap the passed in pixel coordinates to the nearest level grid coordinate.
        /// 	vector is passed by reference and modified
        /// </summary>
        /// <param name = "p_position">the vector to manipulate</param>
        public static void SnapToGrid(ref Vector2 p_position)
        {
            p_position.X = p_position.X - (p_position.X % LevelTilesize) + MapOffset.X;
            p_position.Y = p_position.Y - (p_position.Y % LevelTilesize) + MapOffset.Y;
        }

        /// <summary>
        /// 	Returns the level coordinates which correspond to the path which
        /// 	enemies follow
        /// </summary>
        /// <returns>the path to follow</returns>
        public Point[] GetEnemyPath()
        {
            //create the grid to pass into the pathfinding manager
            var gridCopy = new bool[LevelWidth, LevelHeight];
            for (var i = 0; i < LevelWidth; i++)
            {
                for (var j = 0; j < LevelWidth; j++)
                {
                    gridCopy[i, j] = LevelGrid[i, j] == 0;
                }
            }

            //initialize the pathfinding manager
            GameEngine.GetService<IManagerPathfinding>().SetParams(LevelWidth, LevelHeight, 1, //cost to move to an adjacent cell
                                                                   0, //cost to move diagonally (0 disables diagonal movement)
                                                                   gridCopy);

            //return the path which is returned by the pathfinding manager
            return GameEngine.GetService<IManagerPathfinding>().FindPath(StartPosition, EndPosition);
        }
    }
}